<!DOCTYPE html>
<html lang="zh-cn" dir="ltr">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="fabric-go-sdk # 1、概述 # ​	Fabric的Peer节点和Orderer节点都提供了基于GRPC协议(Google开发的远程过程调用RPC)的接口，通过这些接口可以和Peer节点与Orderer节点进行命令/数据交互，为了简化开发，官方提供了多语言版本的SDK。
fabric-go-sdk官方网址为https://github.com/hyperledger/fabric-sdk-go
pkg目录是fabric-go-sdk的主要实现，internel目录和third_party目录包含了fabric-go-sdk依赖的一些代码。
pkg/fabsdk：Fabric SDK 的主包。此包支持基于配置创建上下文。这些上下文由下面列出的客户端包使用。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/fabsdk
pkg/client/channel：提供通道事务能力。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel
pkg/client/event：提供通道事件能力。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/event
pkg/client/ledger：启用对通道底层账本的查询。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/ledger
pkg/client/resmgmt：提供安装链码等资源管理能力。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt
pkg/client/msp：启用身份管理功能。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/msp
基本工作流程
1) 使用配置实例化一个 fabsdk 实例。 注意：fabsdk 维护缓存，因此您应该最小化 fabsdk 本身的实例。 2) 使用您的 fabsdk 实例创建基于用户和组织的上下文。 注意：通道上下文还需要通道 ID。 3) 使用它的 New func 创建一个客户端实例，传递上下文。 注意：您为所需的每个上下文创建一个新的客户端实例。 4）使用每个客户提供的功能来创建您的解决方案！ 5) 调用 fabsdk.Close() 释放资源和缓存。 2、准备网络环境 # 准备证书文件 # 具体参照solo节点测试
在$GOPATH/src目录下创建一个名为sdktest的文件夹做为项目根目录,在此目录下创建名为fixtures的文件夹存放我们网络相关配置文件。
编辑crypto-config.yaml的文件（这里为一个组织两个节点）
cryptogen generate --config=crypto-config.yaml 生成证书 在fixtures路径下创建一个名为configtx.yaml的文件
编辑configtx.yaml文件
生成创世块文件
生成通道文件
锚节点更新（两个组织都要更新）
完成后：channel-artifacts文件夹 channel.tx Org1MSPanchors.tx Org1MSPanchors.tx genesis.block 配置docker-compose文件">
<meta name="theme-color" content="#FFFFFF">
<meta name="color-scheme" content="light dark"><meta property="og:title" content="fabric-sdk-go详解" />
<meta property="og:description" content="fabric-go-sdk # 1、概述 # ​	Fabric的Peer节点和Orderer节点都提供了基于GRPC协议(Google开发的远程过程调用RPC)的接口，通过这些接口可以和Peer节点与Orderer节点进行命令/数据交互，为了简化开发，官方提供了多语言版本的SDK。
fabric-go-sdk官方网址为https://github.com/hyperledger/fabric-sdk-go
pkg目录是fabric-go-sdk的主要实现，internel目录和third_party目录包含了fabric-go-sdk依赖的一些代码。
pkg/fabsdk：Fabric SDK 的主包。此包支持基于配置创建上下文。这些上下文由下面列出的客户端包使用。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/fabsdk
pkg/client/channel：提供通道事务能力。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel
pkg/client/event：提供通道事件能力。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/event
pkg/client/ledger：启用对通道底层账本的查询。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/ledger
pkg/client/resmgmt：提供安装链码等资源管理能力。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt
pkg/client/msp：启用身份管理功能。参考：https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/msp
基本工作流程
1) 使用配置实例化一个 fabsdk 实例。 注意：fabsdk 维护缓存，因此您应该最小化 fabsdk 本身的实例。 2) 使用您的 fabsdk 实例创建基于用户和组织的上下文。 注意：通道上下文还需要通道 ID。 3) 使用它的 New func 创建一个客户端实例，传递上下文。 注意：您为所需的每个上下文创建一个新的客户端实例。 4）使用每个客户提供的功能来创建您的解决方案！ 5) 调用 fabsdk.Close() 释放资源和缓存。 2、准备网络环境 # 准备证书文件 # 具体参照solo节点测试
在$GOPATH/src目录下创建一个名为sdktest的文件夹做为项目根目录,在此目录下创建名为fixtures的文件夹存放我们网络相关配置文件。
编辑crypto-config.yaml的文件（这里为一个组织两个节点）
cryptogen generate --config=crypto-config.yaml 生成证书 在fixtures路径下创建一个名为configtx.yaml的文件
编辑configtx.yaml文件
生成创世块文件
生成通道文件
锚节点更新（两个组织都要更新）
完成后：channel-artifacts文件夹 channel.tx Org1MSPanchors.tx Org1MSPanchors.tx genesis.block 配置docker-compose文件" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://example.org/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-05-08-fabric-sdk-go%E8%AF%A6%E8%A7%A3/" /><meta property="article:section" content="docs" />
<meta property="article:published_time" content="2021-05-08T20:47:33+00:00" />
<meta property="article:modified_time" content="2021-05-08T20:47:33+00:00" />

<title>fabric-sdk-go详解 | Soulmate</title>
<link rel="manifest" href="/manifest.json">
<link rel="icon" href="/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="/book.min.c58292d36b18b675680ab9baea2029204537b839ea72f258746ec0f32ce8d6c8.css" integrity="sha256-xYKS02sYtnVoCrm66iApIEU3uDnqcvJYdG7A8yzo1sg=" crossorigin="anonymous">
  <script defer src="/flexsearch.min.js"></script>
  <script defer src="/en.search.min.beb4601b1eab618a95e3b0d49ce0487f50ed4cb8eecc3a3bd5f798bdba5ad9f3.js" integrity="sha256-vrRgGx6rYYqV47DUnOBIf1DtTLjuzDo71feYvbpa2fM=" crossorigin="anonymous"></script>
<!--
Made with Book Theme
https://github.com/alex-shpak/hugo-book
-->
  
</head>
<body dir="ltr">
  <input type="checkbox" class="hidden toggle" id="menu-control" />
  <input type="checkbox" class="hidden toggle" id="toc-control" />
  <main class="container flex">
    <aside class="book-menu">
      <div class="book-menu-content">
        
  <nav>
<h2 class="book-brand">
  <a class="flex align-center" href="/"><img src="/logo.png" alt="Logo" /><span>Soulmate</span>
  </a>
</h2>


<div class="book-search">
  <input type="text" id="book-search-input" placeholder="Search" aria-label="Search" maxlength="64" data-hotkeys="s/" />
  <div class="book-search-spinner hidden"></div>
  <ul id="book-search-results"></ul>
</div>












  



  
  <ul>
    
      
        <li class="book-section-flat" >
          
  
  

  
    <input type="checkbox" id="section-074eed0fb8c6f9d99dfeff898388792f" class="toggle"  />
    <label for="section-074eed0fb8c6f9d99dfeff898388792f" class="flex justify-between">
      <a role="button" class="">计算机基础</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/git%E5%9F%BA%E7%A1%80/" class="">Git基础</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/linux%E5%9F%BA%E7%A1%80/" class="">Linux基础</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E5%9F%BA%E7%A1%80/" class="">操作系统基础</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%9F%BA%E7%A1%80/" class="">数据库基础</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E8%AE%A1%E7%AE%97%E6%9C%BA%E5%9F%BA%E7%A1%80/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%BD%91%E7%BB%9C%E5%9F%BA%E7%A1%80/" class="">计算机网络基础</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li class="book-section-flat" >
          
  
  

  
    <span>Golang</span>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-670eda717a06f31447c52422ec93a159" class="toggle"  />
    <label for="section-670eda717a06f31447c52422ec93a159" class="flex justify-between">
      <a role="button" class="">基础</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/%E5%9F%BA%E7%A1%80/2021-04-07-go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%B8%80/" class="">2021 04 07 Go语言基础（一）</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/%E5%9F%BA%E7%A1%80/2021-10-26-go%E8%AF%AD%E8%A8%80%E5%9F%BA%E7%A1%80%E4%BA%8C/" class="">2021 10 26 Go语言基础（二）</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/%E5%9F%BA%E7%A1%80/2021-12-20-benchmark%E6%B5%8B%E8%AF%95/" class="">2021 12 20 Benchmark测试</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/%E5%9F%BA%E7%A1%80/%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-go/" class="">数据结构 Go</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-c453881a62c640f6a4cceec99c02477e" class="toggle"  />
    <label for="section-c453881a62c640f6a4cceec99c02477e" class="flex justify-between">
      <a role="button" class="">高阶</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/%E9%AB%98%E9%98%B6/go%E8%AF%AD%E8%A8%80%E9%AB%98%E9%98%B6%E4%B8%80/" class="">Go语言高阶（一）</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-ee53da12118bfd3e9b35f3e9494ab55b" class="toggle"  />
    <label for="section-ee53da12118bfd3e9b35f3e9494ab55b" class="flex justify-between">
      <a role="button" class="">LeetCode</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/leetcode/2021-10-14-golang%E5%8A%9B%E6%89%A3%E5%88%B7%E9%A2%98%E4%B8%80/" class="">2021 10 14 Golang力扣刷题（一）</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/leetcode/2021-10-28-leetcode%E7%AE%97%E6%B3%95%E6%80%BB%E7%BB%93/" class="">2021 10 28 Leet Code算法总结</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/leetcode/2021-11-04-golang%E5%8A%9B%E6%89%A3%E5%88%B7%E9%A2%98%E4%BA%8C/" class="">2021 11 04 Golang力扣刷题（二）</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/golang/leetcode/%E5%BF%85%E5%88%B7top101/" class="">必刷top101</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li class="book-section-flat" >
          
  
  

  
    <span>区块链</span>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-76bfb65f46ce25a0ff78d6cc4ad47773" class="toggle" checked />
    <label for="section-76bfb65f46ce25a0ff78d6cc4ad47773" class="flex justify-between">
      <a role="button" class="">Fabric</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-05-08-fabric-sdk-go%E8%AF%A6%E8%A7%A3/" class="active">fabric-sdk-go详解</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-1e3df3eda5cf08a9c7e8cc723288fefb" class="toggle"  />
    <label for="section-1e3df3eda5cf08a9c7e8cc723288fefb" class="flex justify-between">
      <a role="button" class="">环境测试</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-03-18-centos%E5%AE%89%E8%A3%85fabric1.2/" class="">centos安装fabric1.2</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-03-22-fabric%E7%BD%91%E7%BB%9C%E4%B8%AD%E7%9A%84%E6%8A%A5%E9%94%99%E4%BA%8C/" class="">2021 03 22 Fabric网络中的报错（二）</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-03-24-fabric%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA/" class="">2021 03 24 Fabric环境搭建</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-03-25-fabric-solo%E8%8A%82%E7%82%B9%E6%B5%8B%E8%AF%95/" class="">2021 03 25 Fabric Solo节点测试</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-03-25-fabric%E5%A4%9A%E6%9C%BA%E6%90%AD%E5%BB%BA/" class="">2021 03 25 Fabric多机搭建</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-05-01-%E6%89%8B%E5%8A%A8%E7%94%9F%E6%88%90ca%E8%AF%81%E4%B9%A6%E6%90%AD%E5%BB%BAfabric%E7%BD%91%E7%BB%9C/" class="">2021 05 01 手动生成ca证书搭建fabric网络</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/2021-12-20-%E9%83%A8%E7%BD%B2tape%E6%B5%8B%E8%AF%95/" class="">2021 12 20 部署tape测试</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E7%8E%AF%E5%A2%83%E6%B5%8B%E8%AF%95/fabric%E7%BD%91%E7%BB%9C%E4%B8%AD%E7%9A%84%E6%8A%A5%E9%94%99%E4%B8%80/" class="">Fabric网络中的报错（一）</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-25aef1d59a561fcefcaecb043ef8afd2" class="toggle"  />
    <label for="section-25aef1d59a561fcefcaecb043ef8afd2" class="flex justify-between">
      <a role="button" class="">配置文件</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/2021-03-29-configtx-yaml%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/" class="">2021 03 29 Configtx Yaml文件详解</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/2021-03-29-crypto-config-yaml%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/" class="">2021 03 29 Crypto Config Yaml文件详解</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/2021-03-30-config-yaml%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/" class="">2021 03 30 Config Yaml文件详解</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/2021-03-30-docker-compose-yaml%E6%96%87%E4%BB%B6%E8%AF%A6%E8%A7%A3/" class="">2021 03 30 Docker Compose Yaml文件详解</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6/2021-05-01-cryptogen%E7%94%9F%E6%88%90%E7%9A%84%E8%AF%81%E4%B9%A6%E8%AF%A6%E8%A7%A3/" class="">2021 05 01 Cryptogen生成的证书详解</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2022-04-14-%E5%8D%87%E7%BA%A7%E9%93%BE%E7%A0%81/" class="">升级链码</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-04-15-fabric-ca%E8%AF%A6%E8%A7%A3/" class="">2021 04 15 Fabric Ca详解</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-04-15-fabric1.4%E5%A4%9A%E9%80%9A%E9%81%93%E5%AE%9E%E9%AA%8C/" class="">2021 04 15 Fabric1.4多通道实验</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-04-17-%E5%A6%82%E4%BD%95%E5%9C%A8%E5%B7%B2%E6%9C%89%E7%BB%84%E7%BB%87%E4%B8%AD%E5%A2%9E%E5%8A%A0%E8%8A%82%E7%82%B9/" class="">2021 04 17 如何在已有组织中增加节点</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-05-02-fabric%E6%B5%8F%E8%A7%88%E5%99%A8%E6%90%AD%E5%BB%BA/" class="">2021 05 02 Fabric浏览器搭建</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2021-05-10-%E6%99%BA%E8%83%BD%E5%90%88%E7%BA%A6/" class="">2021 05 10 智能合约</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2022-02-25-fabric%E7%9B%B8%E5%85%B3%E6%9C%BA%E5%88%B6%E4%B8%8E%E5%8E%9F%E7%90%86/" class="">2022 02 25 Fabric相关机制与原理</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/fabric/2022-03-25-%E5%8C%BA%E5%9D%97%E9%93%BE%E7%BD%91%E7%BB%9C%E6%B7%BB%E5%8A%A0%E7%BB%84%E7%BB%87/" class="">2022 03 25 区块链网络添加组织</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-b07621083aa30b12de4c0333941e479f" class="toggle"  />
    <label for="section-b07621083aa30b12de4c0333941e479f" class="flex justify-between">
      <a role="button" class="">比特币</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/%E6%AF%94%E7%89%B9%E5%B8%81/2022-02-25-%E6%AF%94%E7%89%B9%E5%B8%81%E7%9B%B8%E5%85%B3%E6%9C%BA%E5%88%B6%E4%B8%8E%E5%8E%9F%E7%90%86/" class="">2022 02 25 比特币相关机制与原理</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-ff5477999ef29208270c84e8b56b2758" class="toggle"  />
    <label for="section-ff5477999ef29208270c84e8b56b2758" class="flex justify-between">
      <a role="button" class="">IPFS</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/ipfs/2021-06-02-ipfs%E7%A7%81%E6%9C%89%E7%BD%91%E7%BB%9C%E6%90%AD%E5%BB%BA/" class="">2021 06 02 IP Fs私有网络搭建</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/ipfs/2021-07-08-ipfs%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E4%B8%80/" class="">2021 07 08 IP Fs基本原理（一）</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/ipfs/2021-07-12-ipfs-webui%E5%8F%AF%E8%A7%86%E5%8C%96%E5%B7%A5%E5%85%B7%E6%90%AD%E5%BB%BA/" class="">2021 07 12 Ipfs Webui可视化工具搭建</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/ipfs/2021-12-05-go-ipfs-api/" class="">2021 12 05 Go Ipfs API</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-77a0a17b06e8d04cfb0fba9952941706" class="toggle"  />
    <label for="section-77a0a17b06e8d04cfb0fba9952941706" class="flex justify-between">
      <a role="button" class="">密码学</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/%E5%AF%86%E7%A0%81%E5%AD%A6/2021-03-04-%E5%AF%86%E7%A0%81%E5%AD%A6%E5%9F%BA%E7%A1%80/" class="">2021 03 04 密码学基础</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/%E5%AF%86%E7%A0%81%E5%AD%A6/2021-04-12-%E6%A4%AD%E5%9C%86%E6%9B%B2%E7%BA%BF%E5%8A%A0%E5%AF%86/" class="">2021 04 12 椭圆曲线加密</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/%E5%AF%86%E7%A0%81%E5%AD%A6/2022-08-15-%E5%8C%BA%E5%9D%97%E9%93%BE%E5%AE%89%E5%85%A8%E5%9F%BA%E7%A1%80/" class="">2022 08 15 区块链安全基础</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-2e4d10b323fd668021dbd532575d8790" class="toggle"  />
    <label for="section-2e4d10b323fd668021dbd532575d8790" class="flex justify-between">
      <a role="button" class="">Docker</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/docker/2021-04-30-docker%E5%B8%B8%E7%94%A8%E7%9F%A5%E8%AF%86%E6%80%BB%E7%BB%93/" class="">2021 04 30 Docker常用知识总结</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/docker/docker%E5%9F%BA%E7%A1%80/" class="">Docker基础</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-70383d7f28a7ae4bf840a844eb61aa16" class="toggle"  />
    <label for="section-70383d7f28a7ae4bf840a844eb61aa16" class="flex justify-between">
      <a role="button" class="">共识算法</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/%E5%85%B1%E8%AF%86%E7%AE%97%E6%B3%95/2022-03-26-raft%E5%85%B1%E8%AF%86%E7%AE%97%E6%B3%95/" class="">2022 03 26 Raft共识算法</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E5%8C%BA%E5%9D%97%E9%93%BE/%E5%85%B1%E8%AF%86%E7%AE%97%E6%B3%95/%E5%85%B1%E8%AF%86%E7%AE%97%E6%B3%95%E5%9F%BA%E7%A1%80/" class="">共识算法基础</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li class="book-section-flat" >
          
  
  

  
    <span>数据库</span>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-94f26238d1ca3b5bcd40eadc7a88d726" class="toggle"  />
    <label for="section-94f26238d1ca3b5bcd40eadc7a88d726" class="flex justify-between">
      <a role="button" class="">MySql</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/2021-04-20-mysql%E5%9F%BA%E7%A1%80%E6%80%BB%E7%BB%93/" class="">MySql基础总结</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/mysql/mac%E8%BF%9E%E6%8E%A5%E6%95%B0%E6%8D%AE%E5%BA%93%E6%89%80%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98/" class="">Mac连接数据库所遇到的问题</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li>
          
  
  

  
    <input type="checkbox" id="section-01e4ef5e6295826a1eab8f1a7114ec2c" class="toggle"  />
    <label for="section-01e4ef5e6295826a1eab8f1a7114ec2c" class="flex justify-between">
      <a role="button" class="">Redis</a>
    </label>
  

          
  <ul>
    
      
        <li>
          
  
  

  
    <a href="/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/2022-03-21-redis%E9%9B%86%E7%BE%A4%E6%90%AD%E5%BB%BA/" class="">Redis集群搭建</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/2022-03-20-redis%E5%9F%BA%E7%A1%80/" class="">Redis基础</a>
  

        </li>
      
    
      
        <li>
          
  
  

  
    <a href="/docs/%E6%95%B0%E6%8D%AE%E5%BA%93/redis/2021-05-02-redis%E9%9D%A2%E8%AF%95%E6%80%BB%E7%BB%93/" class="">redis面试总结</a>
  

        </li>
      
    
  </ul>

        </li>
      
    
  </ul>

        </li>
      
    
      
        <li class="book-section-flat" >
          
  
  

  
    <input type="checkbox" id="section-5f7b667081fbae0581cd216f66d5102f" class="toggle"  />
    <label for="section-5f7b667081fbae0581cd216f66d5102f" class="flex justify-between">
      <a role="button" class="">博客</a>
    </label>
  

          
  <ul>
    
  </ul>

        </li>
      
    
  </ul>











  
<ul>
  
  <li>
    <a href="https://gitee.com/chaincode" target="_blank" rel="noopener">
        Gitee
      </a>
  </li>
  
</ul>






</nav>




  <script>(function(){var e=document.querySelector("aside .book-menu-content");addEventListener("beforeunload",function(){localStorage.setItem("menu.scrollTop",e.scrollTop)}),e.scrollTop=localStorage.getItem("menu.scrollTop")})()</script>


 
      </div>
    </aside>

    <div class="book-page">
      <header class="book-header">
        
  <div class="flex align-center justify-between">
  <label for="menu-control">
    <img src="/svg/menu.svg" class="book-icon" alt="Menu" />
  </label>

  <strong>fabric-sdk-go详解</strong>

  <label for="toc-control">
    
    <img src="/svg/toc.svg" class="book-icon" alt="Table of Contents" />
    
  </label>
</div>


  
  <aside class="hidden clearfix">
    
  
<nav id="TableOfContents">
  <ul>
    <li><a href="#fabric-go-sdk">fabric-go-sdk</a>
      <ul>
        <li><a href="#1概述">1、概述</a></li>
        <li><a href="#2准备网络环境">2、准备网络环境</a>
          <ul>
            <li><a href="#准备证书文件">准备证书文件</a></li>
          </ul>
        </li>
        <li><a href="#3配置文件configyaml">3、配置文件config.yaml</a></li>
        <li><a href="#4sdk">4、sdk</a>
          <ul>
            <li><a href="#1-定义所需结构体">1. 定义所需结构体</a></li>
            <li><a href="#2初始化">2、初始化</a></li>
            <li><a href="#3调用创建通道函数及加入通道">3、调用创建通道函数及加入通道</a></li>
            <li><a href="#4创建通道">4、创建通道</a></li>
            <li><a href="#5链码生命周期">5、链码生命周期</a></li>
          </ul>
        </li>
        <li><a href="#5启动项目">5、启动项目</a>
          <ul>
            <li></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>



  </aside>
  
 
      </header>

      
      
  <article class="markdown"><h1 id="fabric-go-sdk">
  fabric-go-sdk
  <a class="anchor" href="#fabric-go-sdk">#</a>
</h1>
<h2 id="1概述">
  1、概述
  <a class="anchor" href="#1%e6%a6%82%e8%bf%b0">#</a>
</h2>
<p>​	Fabric的Peer节点和Orderer节点都提供了基于GRPC协议(Google开发的远程过程调用RPC)的接口，通过这些接口可以和Peer节点与Orderer节点进行命令/数据交互，为了简化开发，官方提供了多语言版本的SDK。</p>
<p>fabric-go-sdk官方网址为<a href="https://github.com/hyperledger/fabric-sdk-go">https://github.com/hyperledger/fabric-sdk-go</a></p>
<p><img src="https://pic1.zhimg.com/80/v2-6ebaeff9885569c3f95fe4cc18252750_1440w.jpg" alt="" /></p>
<p>pkg目录是fabric-go-sdk的主要实现，internel目录和third_party目录包含了fabric-go-sdk依赖的一些代码。</p>
<p>pkg/fabsdk：Fabric SDK 的主包。此包支持基于配置创建上下文。这些上下文由下面列出的客户端包使用。参考：<a href="https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/fabsdk">https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/fabsdk</a></p>
<p>pkg/client/channel：提供通道事务能力。参考：<a href="https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel">https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/channel</a></p>
<p>pkg/client/event：提供通道事件能力。参考：<a href="https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/event">https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/event</a></p>
<p>pkg/client/ledger：启用对通道底层账本的查询。参考：<a href="https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/ledger">https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/ledger</a></p>
<p>pkg/client/resmgmt：提供安装链码等资源管理能力。参考：<a href="https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt">https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt</a></p>
<p>pkg/client/msp：启用身份管理功能。参考：<a href="https://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/msp">https ://godoc.org/github.com/hyperledger/fabric-sdk-go/pkg/client/msp</a></p>
<blockquote>
<p>基本工作流程</p>
<pre tabindex="0"><code>1) 使用配置实例化一个 fabsdk 实例。
   注意：fabsdk 维护缓存，因此您应该最小化 fabsdk 本身的实例。
2) 使用您的 fabsdk 实例创建基于用户和组织的上下文。
   注意：通道上下文还需要通道 ID。
3) 使用它的 New func 创建一个客户端实例，传递上下文。
   注意：您为所需的每个上下文创建一个新的客户端实例。
4）使用每个客户提供的功能来创建您的解决方案！
5) 调用 fabsdk.Close() 释放资源和缓存。
</code></pre></blockquote>
<h2 id="2准备网络环境">
  2、准备网络环境
  <a class="anchor" href="#2%e5%87%86%e5%a4%87%e7%bd%91%e7%bb%9c%e7%8e%af%e5%a2%83">#</a>
</h2>
<h3 id="准备证书文件">
  准备证书文件
  <a class="anchor" href="#%e5%87%86%e5%a4%87%e8%af%81%e4%b9%a6%e6%96%87%e4%bb%b6">#</a>
</h3>
<p><strong>具体参照<a href="https://chaincode.gitee.io/docs/%e5%8c%ba%e5%9d%97%e9%93%be/fabric/%e7%8e%af%e5%a2%83%e6%b5%8b%e8%af%95/2021-03-25-fabric-solo%e8%8a%82%e7%82%b9%e6%b5%8b%e8%af%95/">solo节点测试</a></strong></p>
<ul>
<li>
<p>在<code>$GOPATH/src</code>目录下创建一个名为<code>sdktest</code>的文件夹做为项目根目录,在此目录下创建名为<code>fixtures</code>的文件夹存放我们网络相关配置文件。</p>
<ul>
<li>
<p>编辑<code>crypto-config.yaml</code>的文件（这里为一个组织两个节点）</p>
</li>
<li>
<pre tabindex="0"><code>cryptogen generate --config=crypto-config.yaml    生成证书
</code></pre></li>
</ul>
</li>
<li>
<p>在<code>fixtures</code>路径下创建一个名为<code>configtx.yaml</code>的文件</p>
<ul>
<li>
<p>编辑configtx.yaml文件</p>
</li>
<li>
<p>生成创世块文件</p>
</li>
<li>
<p>生成通道文件</p>
</li>
<li>
<p>锚节点更新（两个组织都要更新）</p>
</li>
<li>
<pre tabindex="0"><code>完成后：channel-artifacts文件夹
channel.tx  Org1MSPanchors.tx  Org1MSPanchors.tx  genesis.block
</code></pre></li>
</ul>
</li>
<li>
<p>配置docker-compose文件</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">version</span>: <span style="color:#e6db74">&#39;2&#39;</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">volumes</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">orderer.example.com</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer0.org1.example.com</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer1.org1.example.com</span>:
</span></span><span style="display:flex;"><span><span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">test</span>:
</span></span><span style="display:flex;"><span><span style="color:#f92672">services</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">orderer.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">container_name</span>: <span style="color:#ae81ff">orderer.example.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">image</span>: <span style="color:#ae81ff">hyperledger/fabric-orderer:2.3</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">environment</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_LOGGING_SPEC=DEBUG</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_LISTENADDRESS=0.0.0.0</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_LISTENPORT=7050</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_GENESISMETHOD=file</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_GENESISFILE=/var/hyperledger/orderer/orderer.genesis.block</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_LOCALMSPID=OrdererMSP</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_LOCALMSPDIR=/var/hyperledger/orderer/msp</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_TLS_ENABLED=true</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_TLS_PRIVATEKEY=/var/hyperledger/orderer/tls/server.key</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_TLS_CERTIFICATE=/var/hyperledger/orderer/tls/server.crt</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">ORDERER_GENERAL_TLS_ROOTCAS=[/var/hyperledger/orderer/tls/ca.crt]</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">working_dir</span>: <span style="color:#ae81ff">/opt/gopath/src/github.com/hyperledger/fabric</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">command</span>: <span style="color:#ae81ff">orderer</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">volumes</span>:
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./channel-artifacts/genesis.block:/var/hyperledger/orderer/orderer.genesis.block</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/msp:/var/hyperledger/orderer/msp</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./crypto-config/ordererOrganizations/example.com/orderers/orderer.example.com/tls/:/var/hyperledger/orderer/tls</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">orderer.example.com:/var/hyperledger/production/orderer</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">7050</span>:<span style="color:#ae81ff">7050</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">test</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer0.org1.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">container_name</span>: <span style="color:#ae81ff">peer0.org1.example.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">image</span>: <span style="color:#ae81ff">hyperledger/fabric-peer:2.3</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">environment</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fixtures_test</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_LOGGING_SPEC=DEBUG</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_ENABLED=true</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_PROFILE_ENABLED=true</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_ID=peer0.org1.example.com</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_ADDRESS=peer0.org1.example.com:7051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_LISTENADDRESS=0.0.0.0:7051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_CHAINCODEADDRESS=peer0.org1.example.com:7052</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:7052</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_GOSSIP_BOOTSTRAP=peer0.org1.example.com:7051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer0.org1.example.com:7051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_LOCALMSPID=Org1MSP</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_STATEDATABASE=CouchDB</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb0:5984</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=123456</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">volumes</span>:
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">/var/run/:/host/var/run/</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp:/etc/hyperledger/fabric/msp</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls:/etc/hyperledger/fabric/tls</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">peer0.org1.example.com:/var/hyperledger/production</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">working_dir</span>: <span style="color:#ae81ff">/opt/gopath/src/github.com/hyperledger/fabric/peer</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">command</span>: <span style="color:#ae81ff">peer node start</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">7051</span>:<span style="color:#ae81ff">7051</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">depends_on</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">orderer.example.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">test</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer1.org1.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">container_name</span>: <span style="color:#ae81ff">peer1.org1.example.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">image</span>: <span style="color:#ae81ff">hyperledger/fabric-peer:2.3</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">environment</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=fixtures_test</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_LOGGING_SPEC=DEBUG</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_ENABLED=true</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_PROFILE_ENABLED=true</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_CERT_FILE=/etc/hyperledger/fabric/tls/server.crt</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_KEY_FILE=/etc/hyperledger/fabric/tls/server.key</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_TLS_ROOTCERT_FILE=/etc/hyperledger/fabric/tls/ca.crt</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_ID=peer1.org1.example.com</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_ADDRESS=peer1.org1.example.com:9051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_LISTENADDRESS=0.0.0.0:9051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_CHAINCODEADDRESS=peer1.org1.example.com:9052</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_CHAINCODELISTENADDRESS=0.0.0.0:9052</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_GOSSIP_EXTERNALENDPOINT=peer1.org1.example.com:9051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_GOSSIP_BOOTSTRAP=peer1.org1.example.com:9051</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_PEER_LOCALMSPID=Org1MSP</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_STATEDATABASE=CouchDB</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb1:5984</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=123456</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">volumes</span>:
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">/var/run/:/host/var/run/</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/msp:/etc/hyperledger/fabric/msp</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">./crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls:/etc/hyperledger/fabric/tls</span>
</span></span><span style="display:flex;"><span>        - <span style="color:#ae81ff">peer1.org1.example.com:/var/hyperledger/production</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">working_dir</span>: <span style="color:#ae81ff">/opt/gopath/src/github.com/hyperledger/fabric/peer</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">command</span>: <span style="color:#ae81ff">peer node start</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">9051</span>:<span style="color:#ae81ff">9051</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">depends_on</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">orderer.example.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">test</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">ca.org1.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">image</span>: <span style="color:#ae81ff">hyperledger/fabric-ca:1.4.9</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">container_name</span>: <span style="color:#ae81ff">ca.org1.example.com</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">environment</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_HOME=/etc/hyperledger/fabric-ca-server</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_SERVER_CA_NAME=ca.org1.example.com</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_SERVER_CA_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_SERVER_CA_KEYFILE=/etc/hyperledger/fabric-ca-server-config/priv_sk</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_SERVER_TLS_ENABLED=true</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_SERVER_TLS_CERTFILE=/etc/hyperledger/fabric-ca-server-config/ca.org1.example.com-cert.pem</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">FABRIC_CA_SERVER_TLS_KEYFILE=/etc/hyperledger/fabric-ca-server-config/priv_sk</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">7054</span>:<span style="color:#ae81ff">7054</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">command</span>: <span style="color:#ae81ff">sh -c &#39;fabric-ca-server start -b admin:adminpw -d&#39;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">volumes</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">./crypto-config/peerOrganizations/org1.example.com/ca/:/etc/hyperledger/fabric-ca-server-config</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">test</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">couchdb0</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">container_name</span>: <span style="color:#ae81ff">couchdb0</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">image</span>: <span style="color:#ae81ff">hyperledger/fabric-couchdb:latest</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">environment</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">COUCHDB_USER=admin</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">COUCHDB_PASSWORD=123456</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#e6db74">&#34;5984:5984&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">test</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">couchdb1</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">container_name</span>: <span style="color:#ae81ff">couchdb1</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">image</span>: <span style="color:#ae81ff">hyperledger/fabric-couchdb:latest</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">environment</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">COUCHDB_USER=admin</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">COUCHDB_PASSWORD=123456</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">ports</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#e6db74">&#34;7984:5984&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">networks</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">test</span>
</span></span></code></pre></div></li>
</ul>
<h2 id="3配置文件configyaml">
  3、配置文件config.yaml
  <a class="anchor" href="#3%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6configyaml">#</a>
</h2>
<p>具体介绍：<a href="https://chaincode.gitee.io/docs/%e5%8c%ba%e5%9d%97%e9%93%be/fabric/%e9%85%8d%e7%bd%ae%e6%96%87%e4%bb%b6/2021-03-30-config-yaml%e6%96%87%e4%bb%b6%e8%af%a6%e8%a7%a3/">config-yaml文件详解</a></p>
<p>改好的配置文件如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-yaml" data-lang="yaml"><span style="display:flex;"><span><span style="color:#f92672">version</span>: <span style="color:#ae81ff">1.0.0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">client</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">organization</span>: <span style="color:#ae81ff">org1</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">logging</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">level</span>: <span style="color:#ae81ff">info</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">cryptoconfig</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/Users/tianzhiwei/go/src/sdktest/fixtures/crypto-config</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">credentialStore</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">path</span>: <span style="color:#e6db74">&#34;/tmp/state-store&#34;</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">cryptoStore</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/tmp/msp</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">BCCSP</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">security</span>:
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">enabled</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">default</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">provider</span>: <span style="color:#e6db74">&#34;SW&#34;</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">hashAlgorithm</span>: <span style="color:#e6db74">&#34;SHA2&#34;</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">softVerify</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>     <span style="color:#f92672">level</span>: <span style="color:#ae81ff">256</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">tlsCerts</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">systemCertPool</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">client</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">key</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/Users/tianzhiwei/go/src/sdktest/fixtures/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/tls/client.key</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">cert</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/Users/tianzhiwei/go/src/sdktest/fixtures/crypto-config/peerOrganizations/org1.example.com/users/User1@org1.example.com/tls/client.crt</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">channels</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">mychannel</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">peers</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">peer0.org1.example.com</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">endorsingPeer</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">chaincodeQuery</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">ledgerQuery</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">eventSource</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">peer1.org1.example.com</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">endorsingPeer</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">chaincodeQuery</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">ledgerQuery</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">eventSource</span>: <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">policies</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">queryChannelConfig</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">minResponses</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">maxTargets</span>: <span style="color:#ae81ff">1</span>
</span></span><span style="display:flex;"><span>        <span style="color:#f92672">retryOpts</span>:
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">attempts</span>: <span style="color:#ae81ff">5</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">initialBackoff</span>: <span style="color:#ae81ff">500ms</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">maxBackoff</span>: <span style="color:#ae81ff">5s</span>
</span></span><span style="display:flex;"><span>          <span style="color:#f92672">backoffFactor</span>: <span style="color:#ae81ff">2.0</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">organizations</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">org1</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">mspid</span>: <span style="color:#ae81ff">Org1MSP</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">cryptoPath</span>:  <span style="color:#ae81ff">peerOrganizations/org1.example.com/users/{username}@org1.example.com/msp</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">peers</span>:
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">peer0.org1.example.com</span>
</span></span><span style="display:flex;"><span>      - <span style="color:#ae81ff">peer1.org1.example.com</span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">ordererorg</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">mspID</span>: <span style="color:#ae81ff">OrdererMSP</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">cryptoPath</span>: <span style="color:#ae81ff">ordererOrganizations/example.com/users/{username}@example.com/msp</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">orderers</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">orderer.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">url</span>: <span style="color:#ae81ff">orderer.example.com:7050</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">grpcOptions</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">ssl-target-name-override</span>: <span style="color:#ae81ff">orderer.example.com</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-time</span>: <span style="color:#ae81ff">0s</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-timeout</span>: <span style="color:#ae81ff">20s</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-permit</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">fail-fast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">allow-insecure</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">tlsCACerts</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/Users/tianzhiwei/go/src/sdktest/fixtures/crypto-config/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">peers</span>:
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer0.org1.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">url</span>: <span style="color:#ae81ff">peer0.org1.example.com:7051</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">grpcOptions</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">ssl-target-name-override</span>: <span style="color:#ae81ff">peer0.org1.example.com</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-time</span>: <span style="color:#ae81ff">0s</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-timeout</span>: <span style="color:#ae81ff">20s</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-permit</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">fail-fast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">allow-insecure</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">tlsCACerts</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/Users/tianzhiwei/go/src/sdktest/fixtures/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer1.org1.example.com</span>:
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">url</span>: <span style="color:#ae81ff">peer1.org1.example.com:9051</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">grpcOptions</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">ssl-target-name-override</span>: <span style="color:#ae81ff">peer1.org1.example.com</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-time</span>: <span style="color:#ae81ff">0s</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-timeout</span>: <span style="color:#ae81ff">20s</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">keep-alive-permit</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">fail-fast</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">allow-insecure</span>: <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>    <span style="color:#f92672">tlsCACerts</span>:
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">path</span>: <span style="color:#ae81ff">/Users/tianzhiwei/go/src/sdktest/fixtures/crypto-config/peerOrganizations/org1.example.com/tlsca/tlsca.org1.example.com-cert.pem</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">entityMatchers</span>:
</span></span><span style="display:flex;"><span>  <span style="color:#f92672">peer</span>:
</span></span><span style="display:flex;"><span>    - <span style="color:#f92672">pattern</span>: <span style="color:#ae81ff">(\w+).org1.example.com:(\d+)</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">urlSubstitutionExp</span>: <span style="color:#ae81ff">${1}.org1.example.com:${2}</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">sslTargetOverrideUrlSubstitutionExp</span>: <span style="color:#ae81ff">${1}.org1.example.com</span>
</span></span><span style="display:flex;"><span>      <span style="color:#f92672">mappedHost</span>: <span style="color:#ae81ff">peer0.org1.example.com</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  
</span></span></code></pre></div><h2 id="4sdk">
  4、sdk
  <a class="anchor" href="#4sdk">#</a>
</h2>
<h3 id="1-定义所需结构体">
  1. 定义所需结构体
  <a class="anchor" href="#1-%e5%ae%9a%e4%b9%89%e6%89%80%e9%9c%80%e7%bb%93%e6%9e%84%e4%bd%93">#</a>
</h3>
<p>在项目路径下新建名为<code>sdkInit</code>的文件夹，此文件夹用于存放实现sdk的代码。在<code>sdkInit</code>路径下新建<code>sdkInfo.go</code>并编辑如下：</p>
<ul>
<li>
<p><code>mspclient &quot;github.com/hyperledger/fabric-sdk-go/pkg/client/msp&quot;</code></p>
<p><code>msp</code>包允许在Fabric网络上创建和更新用户。msp客户端支持以下操作:注册、重注册、登记和获取身份签名。基本工作流为：</p>
<ul>
<li>准备客户端上下文</li>
<li>创建msp客户端</li>
<li>登记用户</li>
<li>注册用户</li>
</ul>
</li>
<li>
<p><code>&quot;github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt&quot;</code></p>
<p><code>resmgmt</code>包用于在Fabric网络中创建和更新资源。它允许管理员创建和/或更新通道，并允许对等节点加入通道。管理员还可以在对等节点上执行链码相关操作，如安装、实例化、升级链码等。基本工作流为：</p>
<ul>
<li>准备客户端上下文</li>
<li>创建资源管理器客户端</li>
<li>创建新通道</li>
<li>节点加入通道</li>
<li>查询对等节点的通道，安装/实例化的链代码等。</li>
</ul>
</li>
<li>
<p><code>contextAPI &quot;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context&quot;</code></p>
<p>提供所需上下文接口</p>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">sdkInit</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mspclient</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/client/msp&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">contextAPI</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">OrgInfo</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">OrgAdminUser</span>          <span style="color:#66d9ef">string</span> <span style="color:#75715e">//  管理员用户名，如&#34;Admin&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgName</span>               <span style="color:#66d9ef">string</span> <span style="color:#75715e">//  组织名，如&#34;Org1&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgMspId</span>              <span style="color:#66d9ef">string</span> <span style="color:#75715e">//  组织MSPid，如&#34;Org1MSP&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgUser</span>               <span style="color:#66d9ef">string</span> <span style="color:#75715e">//  用户名，如&#34;User1&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">orgMspClient</span>          <span style="color:#f92672">*</span><span style="color:#a6e22e">mspclient</span>.<span style="color:#a6e22e">Client</span> <span style="color:#75715e">// MSP客户端
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgAdminClientContext</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">contextAPI</span>.<span style="color:#a6e22e">ClientProvider</span> <span style="color:#75715e">// 客户端上下文信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgResMgmt</span>            <span style="color:#f92672">*</span><span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">Client</span> <span style="color:#75715e">// 资源管理客户端
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgPeerNum</span>            <span style="color:#66d9ef">int</span> <span style="color:#75715e">// 组织节点个数
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrgAnchorFile</span>         <span style="color:#66d9ef">string</span> <span style="color:#75715e">//   锚节点配置文件路径 
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">SdkEnvInfo</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 通道信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ChannelID</span>     <span style="color:#66d9ef">string</span> <span style="color:#75715e">// 通道名称，如&#34;simplecc&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ChannelConfig</span> <span style="color:#66d9ef">string</span> <span style="color:#75715e">// 通道配置文件路径
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#75715e">// 组织信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">Orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 排序服务节点信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrdererAdminUser</span>     <span style="color:#66d9ef">string</span> <span style="color:#75715e">// orederer管理员用户名，如&#34;Admin&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrdererOrgName</span>       <span style="color:#66d9ef">string</span> <span style="color:#75715e">// orderer组织名，如&#34;OrdererOrg&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrdererEndpoint</span>      <span style="color:#66d9ef">string</span> <span style="color:#75715e">// orderer端点，如&#34;orderer.example.com&#34;
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">OrdererClientContext</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">contextAPI</span>.<span style="color:#a6e22e">ClientProvider</span> <span style="color:#75715e">// orderer客户端上下文
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#75715e">// 链码信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ChaincodeID</span>      <span style="color:#66d9ef">string</span> <span style="color:#75715e">// 链码名称
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ChaincodePath</span>    <span style="color:#66d9ef">string</span> <span style="color:#75715e">// 链码路径
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ChaincodeVersion</span> <span style="color:#66d9ef">string</span> <span style="color:#75715e">// 链码版本
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>}
</span></span></code></pre></div><h3 id="2初始化">
  2、初始化
  <a class="anchor" href="#2%e5%88%9d%e5%a7%8b%e5%8c%96">#</a>
</h3>
<p>在<code>sdkInit</code>路径下新建<code>sdkSetting.go</code>并编辑如下：</p>
<ul>
<li><code>&quot;github.com/hyperledger/fabric-sdk-go/pkg/core/config&quot;</code>：获取所需配置文件</li>
<li><code>&quot;github.com/hyperledger/fabric-sdk-go/pkg/fabsdk&quot;</code> ：<code>fabsdk</code>包允许客户端使用Hyperledger Fabric网络。</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">sdkInit</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mb</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-protos-go/msp&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">pb</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-protos-go/peer&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/client/channel&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mspclient</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/client/msp&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/client/resmgmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/errors/status&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/msp&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/core/config&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">lcpackager</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/fabsdk&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;strings&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">Setup</span>(<span style="color:#a6e22e">configFile</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">info</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">SdkEnvInfo</span>) (<span style="color:#f92672">*</span><span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">FabricSDK</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">err</span> <span style="color:#66d9ef">error</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">sdk</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">config</span>.<span style="color:#a6e22e">FromFile</span>(<span style="color:#a6e22e">configFile</span>)) <span style="color:#75715e">// 使用fabsdk包的new方法根据config.yaml文件提供的网络信息初始化sdk
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 为组织获得Client句柄和Context信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">// 初始化组织msp客户端
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">orgMspClient</span>, <span style="color:#a6e22e">err</span> = <span style="color:#a6e22e">mspclient</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">sdk</span>.<span style="color:#a6e22e">Context</span>(), <span style="color:#a6e22e">mspclient</span>.<span style="color:#a6e22e">WithOrg</span>(<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>))
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">// 创建所有所需上下文信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">orgContext</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdk</span>.<span style="color:#a6e22e">Context</span>(<span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">WithUser</span>(<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminUser</span>), <span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">WithOrg</span>(<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>))
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span> = <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">orgContext</span>
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">// 新建客户端资源管理器实例
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">resMgmtClient</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">orgContext</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;根据指定的资源管理客户端Context创建通道管理客户端失败: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span> = <span style="color:#a6e22e">resMgmtClient</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 为Orderer获得Context信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ordererClientContext</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdk</span>.<span style="color:#a6e22e">Context</span>(<span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">WithUser</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">OrdererAdminUser</span>), <span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">WithOrg</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">OrdererOrgName</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">OrdererClientContext</span> = <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">ordererClientContext</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">sdk</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="3调用创建通道函数及加入通道">
  3、调用创建通道函数及加入通道
  <a class="anchor" href="#3%e8%b0%83%e7%94%a8%e5%88%9b%e5%bb%ba%e9%80%9a%e9%81%93%e5%87%bd%e6%95%b0%e5%8f%8a%e5%8a%a0%e5%85%a5%e9%80%9a%e9%81%93">#</a>
</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">CreateAndJoinChannel</span>(<span style="color:#a6e22e">info</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">SdkEnvInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 开始创建通道......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> len(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;通道组织不能为空，请提供组织信息&#34;</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 获得所有组织的签名信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">signIds</span> <span style="color:#f92672">:=</span> []<span style="color:#a6e22e">msp</span>.<span style="color:#a6e22e">SigningIdentity</span>{}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">// Get signing identity that is used to sign create channel request
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">orgSignId</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">orgMspClient</span>.<span style="color:#a6e22e">GetSigningIdentity</span>(<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminUser</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;GetSigningIdentity error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">signIds</span> = append(<span style="color:#a6e22e">signIds</span>, <span style="color:#a6e22e">orgSignId</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 创建通道，createChannel方法在下面定义
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">createChannel</span>(<span style="color:#a6e22e">signIds</span>, <span style="color:#a6e22e">info</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Create channel error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 创建通道成功&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 加入通道......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">// 加入通道
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">JoinChannel</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultResMgmtOpts</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithOrdererEndpoint</span>(<span style="color:#e6db74">&#34;orderer.example.com&#34;</span>)); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;%s peers failed to JoinChannel: %v&#34;</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 加入通道成功&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="4创建通道">
  4、创建通道
  <a class="anchor" href="#4%e5%88%9b%e5%bb%ba%e9%80%9a%e9%81%93">#</a>
</h3>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">createChannel</span>(<span style="color:#a6e22e">signIDs</span> []<span style="color:#a6e22e">msp</span>.<span style="color:#a6e22e">SigningIdentity</span>, <span style="color:#a6e22e">info</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">SdkEnvInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// Channel management client 负责管理通道，如创建更新通道
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">chMgmtClient</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">New</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">OrdererClientContext</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Channel management client create error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 根据channel.tx创建通道
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">req</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">SaveChannelRequest</span>{<span style="color:#a6e22e">ChannelID</span>: <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ChannelConfigPath</span>: <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelConfig</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">SigningIdentities</span>: <span style="color:#a6e22e">signIDs</span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">chMgmtClient</span>.<span style="color:#a6e22e">SaveChannel</span>(<span style="color:#a6e22e">req</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultResMgmtOpts</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithOrdererEndpoint</span>(<span style="color:#e6db74">&#34;orderer.example.com&#34;</span>)); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;error should be nil for SaveChannel of orgchannel: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt;&gt;&gt; 使用每个org的管理员身份更新锚节点配置...&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">//根据锚节点文件更新锚节点，与上面创建通道流程相同
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">i</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">req</span> = <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">SaveChannelRequest</span>{<span style="color:#a6e22e">ChannelID</span>: <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">ChannelConfigPath</span>: <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAnchorFile</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">SigningIdentities</span>: []<span style="color:#a6e22e">msp</span>.<span style="color:#a6e22e">SigningIdentity</span>{<span style="color:#a6e22e">signIDs</span>[<span style="color:#a6e22e">i</span>]}}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> = <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">SaveChannel</span>(<span style="color:#a6e22e">req</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultResMgmtOpts</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithOrdererEndpoint</span>(<span style="color:#e6db74">&#34;orderer.example.com&#34;</span>)); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;SaveChannel for anchor org %s error: %v&#34;</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt;&gt;&gt; 使用每个org的管理员身份更新锚节点配置完成&#34;</span>)
</span></span><span style="display:flex;"><span>	
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h3 id="5链码生命周期">
  5、链码生命周期
  <a class="anchor" href="#5%e9%93%be%e7%a0%81%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f">#</a>
</h3>
<p>链码运行在一个隔离于背书peer节点进程的安全的Docker容器中。链码通过应用提交的交易来初始化以及管理账本状态。从hyperledger fabric v2.0版本开始启用了新的链码生命周期，Fabric 链码生命周期是一个过程，它允许多个组织在使用一个链码之前就如何操作达成一致。Fabric链码生命周期需要组织同意定义一个链码的参数，比如说名称、版本以及链码背书策略。通道成员通过以下四步达成共识。不是通道上的每一个组织都需要完成每一步。</p>
<ul>
<li>
<p>打包链码：这一步可以被一个或者每一个组织完成。</p>
</li>
<li>
<p>安装链码在你的 peer 节点上：每一个用链码的组织需要完成这一步。</p>
</li>
<li>
<p>为你的组织批准链码定义：使用链码的每一个组织需要完成这一步。链码能够在通道上运行之前，链码定义需要被足够多的组织批准来满足通道的生命周期背书（LifecycleEndorsement）策略（默认为大多数组织）。</p>
</li>
<li>
<p>提交链码定义到链上：一旦通道上所需数量的组织已经同意，提交交易需要被提交。提交者首先从已同意组织中的足够的peer节点中收集背书，然后通过提交交易来提交链码声明。</p>
</li>
</ul>
<h4 id="1-添加discoverlocalpeers方法">
  1. 添加<code>DiscoverLocalPeers</code>方法
  <a class="anchor" href="#1-%e6%b7%bb%e5%8a%a0discoverlocalpeers%e6%96%b9%e6%b3%95">#</a>
</h4>
<p><font color='red'><code>DiscoverLocalPeers</code>方法可以自动查找的所有节点</font></p>
<p>在<code>sdkInit</code>路径下新建一个名为<code>intergration.go</code>的文件。编辑如下：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">sdkInit</span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/errors/retry&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/errors/status&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">contextAPI</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/context&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fabAPI</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">contextImpl</span> <span style="color:#e6db74">&#34;github.com/hyperledger/fabric-sdk-go/pkg/context&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span><span style="color:#75715e">// 查找本地节点
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#a6e22e">ctxProvider</span> <span style="color:#a6e22e">contextAPI</span>.<span style="color:#a6e22e">ClientProvider</span>, <span style="color:#a6e22e">expectedPeers</span> <span style="color:#66d9ef">int</span>) ([]<span style="color:#a6e22e">fabAPI</span>.<span style="color:#a6e22e">Peer</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">ctx</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">contextImpl</span>.<span style="color:#a6e22e">NewLocal</span>(<span style="color:#a6e22e">ctxProvider</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;error creating local context: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">discoveredPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">NewInvoker</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">TestRetryOpts</span>)).<span style="color:#a6e22e">Invoke</span>(
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">func</span>() (<span style="color:#66d9ef">interface</span>{}, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">peers</span>, <span style="color:#a6e22e">serviceErr</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">ctx</span>.<span style="color:#a6e22e">LocalDiscoveryService</span>().<span style="color:#a6e22e">GetPeers</span>()
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">serviceErr</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;getting peers for MSP [%s] error: %v&#34;</span>, <span style="color:#a6e22e">ctx</span>.<span style="color:#a6e22e">Identifier</span>().<span style="color:#a6e22e">MSPID</span>, <span style="color:#a6e22e">serviceErr</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> len(<span style="color:#a6e22e">peers</span>) &lt; <span style="color:#a6e22e">expectedPeers</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">TestStatus</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">GenericTransient</span>.<span style="color:#a6e22e">ToInt32</span>(), <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;Expecting %d peers but got %d&#34;</span>, <span style="color:#a6e22e">expectedPeers</span>, len(<span style="color:#a6e22e">peers</span>)), <span style="color:#66d9ef">nil</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">peers</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>		},
</span></span><span style="display:flex;"><span>	)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">discoveredPeers</span>.([]<span style="color:#a6e22e">fabAPI</span>.<span style="color:#a6e22e">Peer</span>), <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h4 id="2-链码自动化生命周期">
  2. 链码自动化生命周期
  <a class="anchor" href="#2-%e9%93%be%e7%a0%81%e8%87%aa%e5%8a%a8%e5%8c%96%e7%94%9f%e5%91%bd%e5%91%a8%e6%9c%9f">#</a>
</h4>
<p>继续在<code>sdkSetting.go</code>文件中编辑如下：</p>
<ul>
<li>导入所需包</li>
</ul>
<pre tabindex="0"><code>import (
	[......]
	mb &#34;github.com/hyperledger/fabric-protos-go/msp&#34;
	pb &#34;github.com/hyperledger/fabric-protos-go/peer&#34;
	&#34;github.com/hyperledger/fabric-sdk-go/pkg/client/channel&#34;
	&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/errors/status&#34;
	&#34;github.com/hyperledger/fabric-sdk-go/pkg/common/providers/fab&#34;
	lcpackager &#34;github.com/hyperledger/fabric-sdk-go/pkg/fab/ccpackager/lifecycle&#34;
	&#34;github.com/hyperledger/fabric-sdk-go/third_party/github.com/hyperledger/fabric/common/policydsl&#34;
	&#34;strings&#34;
)
</code></pre><ul>
<li>打包链码</li>
</ul>
<p>在被安装到<code>peer</code>节点之前，链码需要被打包进一个<code>tar</code>文件。当你创建一个链码包的时候，你需要提交一个用来创建简明易读的包描述的链码包标签。</p>
<p>使用<code>fabric-go-sdk</code>将会自动以这个格式来创建文件。</p>
<ul>
<li>链码需要被打包进一个以 <code>.tar.gz</code> 文件扩展名结尾的<code>tar</code>文件。</li>
<li><code>tar</code>文件需要包含两个文件（没有目录）：<code>metadata.json</code>和另一个包含了链码文件的 tar 文件<code>code.tar.gz</code>。</li>
<li><code>metadata.json</code>包含了指定链码语言、代码路径、以及包标签的 JSON 文件。</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">packageCC</span>(<span style="color:#a6e22e">ccName</span>, <span style="color:#a6e22e">ccVersion</span>, <span style="color:#a6e22e">ccpath</span> <span style="color:#66d9ef">string</span>) (<span style="color:#66d9ef">string</span>, []<span style="color:#66d9ef">byte</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>   
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">label</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">ccName</span> <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;_&#34;</span> <span style="color:#f92672">+</span> <span style="color:#a6e22e">ccVersion</span> <span style="color:#75715e">// 链码的标签
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">desc</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">lcpackager</span>.<span style="color:#a6e22e">Descriptor</span>{   <span style="color:#75715e">// 使用lcpackager包中的Descriptor结构体添加描述信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">Path</span>:  <span style="color:#a6e22e">ccpath</span>, <span style="color:#75715e">//链码路径
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">Type</span>:  <span style="color:#a6e22e">pb</span>.<span style="color:#a6e22e">ChaincodeSpec_GOLANG</span>, <span style="color:#75715e">//链码的语言
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">Label</span>: <span style="color:#a6e22e">label</span>, <span style="color:#75715e">// 链码的标签
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">ccPkg</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">lcpackager</span>.<span style="color:#a6e22e">NewCCPackage</span>(<span style="color:#a6e22e">desc</span>) <span style="color:#75715e">// 使用lcpackager包中NewCCPackage方法对链码进行打包
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#e6db74">&#34;&#34;</span>, <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Package chaincode source error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">desc</span>.<span style="color:#a6e22e">Label</span>, <span style="color:#a6e22e">ccPkg</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>安装链码</li>
</ul>
<p>你需要在每个要执行和背书交易的peer节点上安装链码包。使用SDK时，你需要以 <code>Peer Administrator</code>（peer所在组织的管理员） 的身份来完成这步。链码安装后，你的 peer 节点会构建链码，并且如果你的链码有问题，会返回一个构建错误。**建议每个组织只打包链码一次，然后安装相同的包在属于他们组织的每一个peer节点上。**如果某个通道希望确保每个组织都运行同样的链码，某一个组织可以打包链码并通过带外数据（不通过链上）把它发送给其他通道成员.</p>
<p>通过指令成功安装链码后会返回链码包标识符，它是包标签和包哈希值的结合。这个包标识符用来关联安装在你的peer节点上的链码包已被批准的链码。为下一步的操作保存这个标识符。你也可以查询安装在peer节点上的包来查看包标识符。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">installCC</span>(<span style="color:#a6e22e">label</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">ccPkg</span> []<span style="color:#66d9ef">byte</span>, <span style="color:#a6e22e">orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">installCCReq</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">LifecycleInstallCCRequest</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Label</span>:   <span style="color:#a6e22e">label</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Package</span>: <span style="color:#a6e22e">ccPkg</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 使用lcpackager中的ComputePackageID方法查询并返回链码的packageID
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">packageID</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">lcpackager</span>.<span style="color:#a6e22e">ComputePackageID</span>(<span style="color:#a6e22e">installCCReq</span>.<span style="color:#a6e22e">Label</span>, <span style="color:#a6e22e">installCCReq</span>.<span style="color:#a6e22e">Package</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgPeerNum</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 检查是否安装链码，如果未安装则继续执行
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">flag</span>, <span style="color:#a6e22e">_</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">checkInstalled</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">orgPeers</span>[<span style="color:#ae81ff">0</span>], <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>); <span style="color:#a6e22e">flag</span> <span style="color:#f92672">==</span> <span style="color:#66d9ef">false</span> {
</span></span><span style="display:flex;"><span>            <span style="color:#75715e">// 使用resmgmt中的LifecycleInstallCC方法安装链码，其中WithRetry方法为安装不成功时重试安装，DefaultResMgmtOpts为默认的重试安装规则
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleInstallCC</span>(<span style="color:#a6e22e">installCCReq</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>(<span style="color:#a6e22e">orgPeers</span><span style="color:#f92672">...</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultResMgmtOpts</span>)); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;LifecycleInstallCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span><span style="color:#75715e">//检查是否安装过链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">checkInstalled</span>(<span style="color:#a6e22e">packageID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">peer</span> <span style="color:#a6e22e">fab</span>.<span style="color:#a6e22e">Peer</span>, <span style="color:#a6e22e">client</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">Client</span>) (<span style="color:#66d9ef">bool</span>, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">flag</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">client</span>.<span style="color:#a6e22e">LifecycleQueryInstalledCC</span>(<span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>(<span style="color:#a6e22e">peer</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">flag</span>, <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;LifecycleQueryInstalledCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">t</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">resp1</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">t</span>.<span style="color:#a6e22e">PackageID</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">packageID</span> { 
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">flag</span> = <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">flag</span>, <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>获取已安装链码包</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">getInstalledCCPackage</span>(<span style="color:#a6e22e">packageID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// use org1
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 使用resmgmt中的LifecycleGetInstalledCCPackage方法，对于给定的packageID检索已安装的链码包
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleGetInstalledCCPackage</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>([]<span style="color:#a6e22e">fab</span>.<span style="color:#a6e22e">Peer</span>{<span style="color:#a6e22e">orgPeers</span>[<span style="color:#ae81ff">0</span>]}<span style="color:#f92672">...</span>)); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;LifecycleGetInstalledCCPackage error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>查询安装</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">queryInstalled</span>(<span style="color:#a6e22e">packageID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 使用resmgmt中的LifecycleQueryInstalledCC方法，返回在指定节点上安装的链码packageID
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleQueryInstalledCC</span>(<span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>([]<span style="color:#a6e22e">fab</span>.<span style="color:#a6e22e">Peer</span>{<span style="color:#a6e22e">orgPeers</span>[<span style="color:#ae81ff">0</span>]}<span style="color:#f92672">...</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;LifecycleQueryInstalledCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">packageID1</span> <span style="color:#f92672">:=</span> <span style="color:#e6db74">&#34;&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">t</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">resp1</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">t</span>.<span style="color:#a6e22e">PackageID</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">packageID</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">packageID1</span> = <span style="color:#a6e22e">t</span>.<span style="color:#a6e22e">PackageID</span>
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 查询的packageID与给定的packageID不一致则报错
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> !<span style="color:#a6e22e">strings</span>.<span style="color:#a6e22e">EqualFold</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">packageID1</span>) {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;check package id error&#34;</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>
<p>各组织批准链码</p>
<p>通过 链码定义来管理链码。当通道成员批准一个链码定义，这个批准便作为一个组织在接受链码参数方面的投票。这些同意的组织定义允许通道成员在链码可以在通道上使用之前达成一致意见（同意链码运行在此通道上）。链码定义包含了以下需要持续在组织之间保持一致的参数：</p>
<ul>
<li>名称：应用调用链码时使用的名称。</li>
<li>版本：一个版本号或者和给定链码包关联的值。如果你升级链码二进制文件（译者注：打包后的链码文件），你也需要改变你的链码版本。</li>
<li>序列号：链码被定义的次数。这个值是一个整数，并且被用来追踪链码的更新次数。例如当你第一次安装并且同意一个链码定义，这个序列号会是1。当你下一次更新链码，序列号会是2。</li>
<li>背书策略：哪些组织需要执行并且验证交易输出。背书策略可以表达为传递给 CLI 工具的字符串或者它能参考通道配置中的一个策略。默认情况下，背书策略设置为 <code>Channel/Application/Endorsement</code>，默认通道中大多数组织为一笔交易背书。</li>
<li>集合配置（私有数据集合配置）：和你链码相关的私有数据集合定义文件的路径。了解更多关于私有数据集合的信息。</li>
<li><code>ESCC/VSCC</code>插件：这个链码使用的定制的背书或者验证插件名称。</li>
<li>初始化： 如果你使用 Fabric Chaincode Shim API 提供的低级别的 API，你的链码需要包含用来初始化链码的 <code>Init</code> 方法。链码接口需要这个方法，但不必要被你的应用调用。 当你批准一个链码定义时，你可以指定是否 <code>Init</code> 方法必须在调用（调用非 init 方法）之前被执行。如果你指定需要 <code>Init</code>，Fabric 会确保<code>Init</code> 方法在链码中的其他方法之前被调用，并且只会被调用一次。 请求执行 <code>Init</code> 方法允许你实现链码初始化时运行的逻辑，例如设置一些初始状态。每次你的链码版本更新，你都需要调用 <code>Init</code> 来初始化链码，假定链码定义增加了版本号意味着 <code>Init</code> 是需要的。</li>
</ul>
</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">approveCC</span>(<span style="color:#a6e22e">packageID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">ccName</span>, <span style="color:#a6e22e">ccVersion</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">sequence</span> <span style="color:#66d9ef">int64</span>, <span style="color:#a6e22e">channelID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>, <span style="color:#a6e22e">ordererEndpoint</span> <span style="color:#66d9ef">string</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mspIDs</span> <span style="color:#f92672">:=</span> []<span style="color:#66d9ef">string</span>{}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 获取各个组织的mspID
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">mspIDs</span> = append(<span style="color:#a6e22e">mspIDs</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgMspId</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 签名策略，由所有给出的mspid签名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ccPolicy</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">policydsl</span>.<span style="color:#a6e22e">SignedByNOutOfGivenRole</span>(int32(len(<span style="color:#a6e22e">mspIDs</span>)), <span style="color:#a6e22e">mb</span>.<span style="color:#a6e22e">MSPRole_MEMBER</span>, <span style="color:#a6e22e">mspIDs</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// approve所需参数
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">approveCCReq</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">LifecycleApproveCCRequest</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Name</span>:              <span style="color:#a6e22e">ccName</span>,      <span style="color:#75715e">// 链码名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">Version</span>:           <span style="color:#a6e22e">ccVersion</span>,   <span style="color:#75715e">// 版本
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">PackageID</span>:         <span style="color:#a6e22e">packageID</span>,   <span style="color:#75715e">// 链码包id
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">Sequence</span>:          <span style="color:#a6e22e">sequence</span>,    <span style="color:#75715e">// 序列号
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">EndorsementPlugin</span>: <span style="color:#e6db74">&#34;escc&#34;</span>,      <span style="color:#75715e">// 系统内置链码escc
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">ValidationPlugin</span>:  <span style="color:#e6db74">&#34;vscc&#34;</span>,      <span style="color:#75715e">// 系统内置链码vscc
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">SignaturePolicy</span>:   <span style="color:#a6e22e">ccPolicy</span>,    <span style="color:#75715e">// 组织签名策略
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">InitRequired</span>:      <span style="color:#66d9ef">true</span>,        <span style="color:#75715e">// 是否初始化
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgPeerNum</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;&gt;&gt;&gt; chaincode approved by %s peers:\n&#34;</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">p</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgPeers</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;	%s\n&#34;</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">URL</span>())
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// 使用resmgmt中的LifecycleApproveCC方法为组织批准链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleApproveCC</span>(<span style="color:#a6e22e">channelID</span>, <span style="color:#a6e22e">approveCCReq</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>(<span style="color:#a6e22e">orgPeers</span><span style="color:#f92672">...</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithOrdererEndpoint</span>(<span style="color:#a6e22e">ordererEndpoint</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultResMgmtOpts</span>));<span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;LifecycleApproveCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>查询已批准的链码</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">queryApprovedCC</span>(<span style="color:#a6e22e">ccName</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">sequence</span> <span style="color:#66d9ef">int64</span>, <span style="color:#a6e22e">channelID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// queryApproved所需参数
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>    <span style="color:#a6e22e">queryApprovedCCReq</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">LifecycleQueryApprovedCCRequest</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Name</span>:     <span style="color:#a6e22e">ccName</span>,  <span style="color:#75715e">// 链码名称
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">Sequence</span>: <span style="color:#a6e22e">sequence</span>,<span style="color:#75715e">// 序列号
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgPeerNum</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">// Query approve cc
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">p</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgPeers</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">resp</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">NewInvoker</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">TestRetryOpts</span>)).<span style="color:#a6e22e">Invoke</span>(
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">func</span>() (<span style="color:#66d9ef">interface</span>{}, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>                    <span style="color:#75715e">// LifecycleQueryApprovedCC返回有关已批准的链码定义的信息
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>					<span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleQueryApprovedCC</span>(<span style="color:#a6e22e">channelID</span>, <span style="color:#a6e22e">queryApprovedCCReq</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>(<span style="color:#a6e22e">p</span>))
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">TestStatus</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">GenericTransient</span>.<span style="color:#a6e22e">ToInt32</span>(), <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;LifecycleQueryApprovedCC returned error: %v&#34;</span>, <span style="color:#a6e22e">err</span>), <span style="color:#66d9ef">nil</span>)
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>				},
</span></span><span style="display:flex;"><span>			)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Org %s Peer %s NewInvoker error: %v&#34;</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">URL</span>(), <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">resp</span><span style="color:#f92672">==</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Org %s Peer %s Got nil invoker&#34;</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>, <span style="color:#a6e22e">p</span>.<span style="color:#a6e22e">URL</span>())
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>检查智能合约是否就绪</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">checkCCCommitReadiness</span>(<span style="color:#a6e22e">packageID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">ccName</span>, <span style="color:#a6e22e">ccVersion</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">sequence</span> <span style="color:#66d9ef">int64</span>, <span style="color:#a6e22e">channelID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mspIds</span> <span style="color:#f92672">:=</span> []<span style="color:#66d9ef">string</span>{}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">mspIds</span> = append(<span style="color:#a6e22e">mspIds</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgMspId</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 签名策略，由所有给出的mspid签名
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">ccPolicy</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">policydsl</span>.<span style="color:#a6e22e">SignedByNOutOfGivenRole</span>(int32(len(<span style="color:#a6e22e">mspIds</span>)), <span style="color:#a6e22e">mb</span>.<span style="color:#a6e22e">MSPRole_MEMBER</span>, <span style="color:#a6e22e">mspIds</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// 所需所有参数，同上
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">req</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">LifecycleCheckCCCommitReadinessRequest</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Name</span>:              <span style="color:#a6e22e">ccName</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Version</span>:           <span style="color:#a6e22e">ccVersion</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#75715e">//PackageID:         packageID,
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>		<span style="color:#a6e22e">EndorsementPlugin</span>: <span style="color:#e6db74">&#34;escc&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ValidationPlugin</span>:  <span style="color:#e6db74">&#34;vscc&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">SignaturePolicy</span>:   <span style="color:#a6e22e">ccPolicy</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Sequence</span>:          <span style="color:#a6e22e">sequence</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">InitRequired</span>:      <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgPeerNum</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">p</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgPeers</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">resp</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">NewInvoker</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">TestRetryOpts</span>)).<span style="color:#a6e22e">Invoke</span>(
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">func</span>() (<span style="color:#66d9ef">interface</span>{}, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>                    <span style="color:#75715e">// 使用resmgmt中的LifecycleCheckCCCommitReadiness方法检查链代码的“提交准备”,返回组织批准。
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>					<span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleCheckCCCommitReadiness</span>(<span style="color:#a6e22e">channelID</span>, <span style="color:#a6e22e">req</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>(<span style="color:#a6e22e">p</span>))
</span></span><span style="display:flex;"><span>					<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;LifecycleCheckCCCommitReadiness cc = %v, = %v\n&#34;</span>, <span style="color:#a6e22e">ccName</span>, <span style="color:#a6e22e">resp1</span>)
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">TestStatus</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">GenericTransient</span>.<span style="color:#a6e22e">ToInt32</span>(), <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;LifecycleCheckCCCommitReadiness returned error: %v&#34;</span>, <span style="color:#a6e22e">err</span>), <span style="color:#66d9ef">nil</span>)
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#a6e22e">flag</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">r</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">resp1</span>.<span style="color:#a6e22e">Approvals</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#a6e22e">flag</span> = <span style="color:#a6e22e">flag</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">r</span>
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">if</span> !<span style="color:#a6e22e">flag</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">TestStatus</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">GenericTransient</span>.<span style="color:#a6e22e">ToInt32</span>(), <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;LifecycleCheckCCCommitReadiness returned : %v&#34;</span>, <span style="color:#a6e22e">resp1</span>), <span style="color:#66d9ef">nil</span>)
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>				},
</span></span><span style="display:flex;"><span>			)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;NewInvoker error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">resp</span><span style="color:#f92672">==</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Got nill invoker response&#34;</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>提交智能合约定义</li>
</ul>
<p>一旦足够多的通道成员同意一个链码定义，某个组织能够提交定义到通道。你可以用上述 <code>checkcommitreadiness</code> 方法在将链码定义提交到通道之前，基于哪个通道成员已经批准了该定义，来检查提交链码定义是否应该成功。（根据通道成员同意的状况，来判断提交是否可能成功）。提交交易请求首先发送给通道成员的 peer节点，peer节点会查询链码定义被他们组织同意的状况，并且为定义背书如果所在组织已经同意了。交易然后提交给排序服务，排序服务会把链码定义提交给通道。提交定义交易需要以 Organization Administrator 身份来提交。</p>
<p>链码在被成功提交到通道之前，需要被同意的组织的数量是通过 <code>Channel/Application/LifecycleEndorsement</code> 策略来管理的。默认情况下，这个策略需要通道中大多数的组织来给交易背书。生命周期背书策略不同于链码背书策略。例如，尽管一个链码背书策略只需要一个或两个组织的签名，根据默认策略大多数的通道成员仍然需要批准链码定义。当提交一个通道定义，你需要面向足够多的 peer 组织，以确保你的生命周期背书策略被满足。</p>
<p>你也可以设置 <code>Channel/Application/LifecycleEndorsement</code> 策略为一个签名策略并且明确指明通道上可以批准链码定义的组织集合。这允许你创建一个其中大多数组织作为链码管理者并且治理通道业务逻辑的通道。如果你的通道有大量的Idemix（身份混合，实现零知识证明）组织，你也可以用一个签名策略（策略只需要一个签名），因为这些组织不能批准链码定义或者为链码背书并且可能阻碍通道达成大多数成员同意的结果。</p>
<p>一个组织在不安装链码包的条件下能够批准链码定义。如果一个组织不需要使用链码，他们可以在没有包身份的情况下批准一个链码定义来确保生命周期背书策略被满足。</p>
<p>在链码定义已经提交到通道上后，链码容器会在所有的链码安装到的 peer 节点上启动，来允许通道成员开始使用链码。可能会花费几分钟的时间来启动链码容器。你可以用链码定义来要求调用 <code>Init</code> 方法初始化链码。如果 <code>Init</code> 方法调用是需要的，链码的第一个调用必须是调用 <code>Init</code> 方法。<code>Init</code> 方法的调用服从于链码的背书策略。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">commitCC</span>(<span style="color:#a6e22e">ccName</span>, <span style="color:#a6e22e">ccVersion</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">sequence</span> <span style="color:#66d9ef">int64</span>, <span style="color:#a6e22e">channelID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>, <span style="color:#a6e22e">ordererEndpoint</span> <span style="color:#66d9ef">string</span>) <span style="color:#66d9ef">error</span>{
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">mspIDs</span> <span style="color:#f92672">:=</span> []<span style="color:#66d9ef">string</span>{}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">mspIDs</span> = append(<span style="color:#a6e22e">mspIDs</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgMspId</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">ccPolicy</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">policydsl</span>.<span style="color:#a6e22e">SignedByNOutOfGivenRole</span>(int32(len(<span style="color:#a6e22e">mspIDs</span>)), <span style="color:#a6e22e">mb</span>.<span style="color:#a6e22e">MSPRole_MEMBER</span>, <span style="color:#a6e22e">mspIDs</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// commit所需参数信息，内容同上
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">req</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">LifecycleCommitCCRequest</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Name</span>:              <span style="color:#a6e22e">ccName</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Version</span>:           <span style="color:#a6e22e">ccVersion</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Sequence</span>:          <span style="color:#a6e22e">sequence</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">EndorsementPlugin</span>: <span style="color:#e6db74">&#34;escc&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ValidationPlugin</span>:  <span style="color:#e6db74">&#34;vscc&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">SignaturePolicy</span>:   <span style="color:#a6e22e">ccPolicy</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">InitRequired</span>:      <span style="color:#66d9ef">true</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// LifecycleCommitCC将链代码提交给给定的通道
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">orgs</span>[<span style="color:#ae81ff">0</span>].<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleCommitCC</span>(<span style="color:#a6e22e">channelID</span>, <span style="color:#a6e22e">req</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithOrdererEndpoint</span>(<span style="color:#a6e22e">ordererEndpoint</span>), <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultResMgmtOpts</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;LifecycleCommitCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>查询已提交的智能合约定义</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">queryCommittedCC</span>( <span style="color:#a6e22e">ccName</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">channelID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">sequence</span> <span style="color:#66d9ef">int64</span>, <span style="color:#a6e22e">orgs</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">req</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">LifecycleQueryCommittedCCRequest</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Name</span>: <span style="color:#a6e22e">ccName</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgs</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">orgPeers</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">DiscoverLocalPeers</span>(<span style="color:#f92672">*</span><span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgAdminClientContext</span>, <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgPeerNum</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;DiscoverLocalPeers error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">p</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">orgPeers</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">resp</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">NewInvoker</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">TestRetryOpts</span>)).<span style="color:#a6e22e">Invoke</span>(
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">func</span>() (<span style="color:#66d9ef">interface</span>{}, <span style="color:#66d9ef">error</span>) {
</span></span><span style="display:flex;"><span>                    <span style="color:#75715e">// LifecycleQueryCommittedCC查询给定通道上提交的链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>					<span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgResMgmt</span>.<span style="color:#a6e22e">LifecycleQueryCommittedCC</span>(<span style="color:#a6e22e">channelID</span>, <span style="color:#a6e22e">req</span>, <span style="color:#a6e22e">resmgmt</span>.<span style="color:#a6e22e">WithTargets</span>(<span style="color:#a6e22e">p</span>))
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">TestStatus</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">GenericTransient</span>.<span style="color:#a6e22e">ToInt32</span>(), <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;LifecycleQueryCommittedCC returned error: %v&#34;</span>, <span style="color:#a6e22e">err</span>), <span style="color:#66d9ef">nil</span>)
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#a6e22e">flag</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">false</span>
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">r</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">resp1</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">r</span>.<span style="color:#a6e22e">Name</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">ccName</span> <span style="color:#f92672">&amp;&amp;</span> <span style="color:#a6e22e">r</span>.<span style="color:#a6e22e">Sequence</span> <span style="color:#f92672">==</span> <span style="color:#a6e22e">sequence</span> {
</span></span><span style="display:flex;"><span>							<span style="color:#a6e22e">flag</span> = <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>							<span style="color:#66d9ef">break</span>
</span></span><span style="display:flex;"><span>						}
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">if</span> !<span style="color:#a6e22e">flag</span> {
</span></span><span style="display:flex;"><span>						<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">TestStatus</span>, <span style="color:#a6e22e">status</span>.<span style="color:#a6e22e">GenericTransient</span>.<span style="color:#a6e22e">ToInt32</span>(), <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;LifecycleQueryCommittedCC returned : %v&#34;</span>, <span style="color:#a6e22e">resp1</span>), <span style="color:#66d9ef">nil</span>)
</span></span><span style="display:flex;"><span>					}
</span></span><span style="display:flex;"><span>					<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">resp1</span>, <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>				},
</span></span><span style="display:flex;"><span>			)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span>  <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;NewInvoker error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">resp</span><span style="color:#f92672">==</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>				<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Got nil invoker response&#34;</span>)
</span></span><span style="display:flex;"><span>			}
</span></span><span style="display:flex;"><span>		}
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>智能合约初始化</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">initCC</span>(<span style="color:#a6e22e">ccName</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">upgrade</span> <span style="color:#66d9ef">bool</span>, <span style="color:#a6e22e">channelID</span> <span style="color:#66d9ef">string</span>, <span style="color:#a6e22e">org</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">OrgInfo</span>, <span style="color:#a6e22e">sdk</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">FabricSDK</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 准备通道客户端上下文
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">clientChannelContext</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdk</span>.<span style="color:#a6e22e">ChannelContext</span>(<span style="color:#a6e22e">channelID</span>, <span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">WithUser</span>(<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgUser</span>), <span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">WithOrg</span>(<span style="color:#a6e22e">org</span>.<span style="color:#a6e22e">OrgName</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 通道客户端用于查询执行交易
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">client</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">channel</span>.<span style="color:#a6e22e">New</span>(<span style="color:#a6e22e">clientChannelContext</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Failed to create new channel client: %s&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 调用链码初始化
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">err</span> = <span style="color:#a6e22e">client</span>.<span style="color:#a6e22e">Execute</span>(<span style="color:#a6e22e">channel</span>.<span style="color:#a6e22e">Request</span>{<span style="color:#a6e22e">ChaincodeID</span>: <span style="color:#a6e22e">ccName</span>, <span style="color:#a6e22e">Fcn</span>: <span style="color:#e6db74">&#34;init&#34;</span>, <span style="color:#a6e22e">Args</span>: <span style="color:#66d9ef">nil</span>, <span style="color:#a6e22e">IsInit</span>: <span style="color:#66d9ef">true</span>},
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">channel</span>.<span style="color:#a6e22e">WithRetry</span>(<span style="color:#a6e22e">retry</span>.<span style="color:#a6e22e">DefaultChannelOpts</span>))
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;Failed to init: %s&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><ul>
<li>智能合约完整生命周期（即整合调用上述方法）</li>
</ul>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">CreateCCLifecycle</span>(<span style="color:#a6e22e">info</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">SdkEnvInfo</span>, <span style="color:#a6e22e">sequence</span> <span style="color:#66d9ef">int64</span>, <span style="color:#a6e22e">upgrade</span> <span style="color:#66d9ef">bool</span>, <span style="color:#a6e22e">sdk</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">fabsdk</span>.<span style="color:#a6e22e">FabricSDK</span>) <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> len(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>) <span style="color:#f92672">==</span> <span style="color:#ae81ff">0</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;the number of organization should not be zero.&#34;</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 打包链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 开始打包链码......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">label</span>, <span style="color:#a6e22e">ccPkg</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">packageCC</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeVersion</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodePath</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;pakcagecc error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">packageID</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">lcpackager</span>.<span style="color:#a6e22e">ComputePackageID</span>(<span style="color:#a6e22e">label</span>, <span style="color:#a6e22e">ccPkg</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 打包链码成功&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 安装链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 开始安装链码......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">installCC</span>(<span style="color:#a6e22e">label</span>, <span style="color:#a6e22e">ccPkg</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;installCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 检索已安装链码包
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">getInstalledCCPackage</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>[<span style="color:#ae81ff">0</span>]); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;getInstalledCCPackage error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 查询已安装链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">queryInstalled</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>[<span style="color:#ae81ff">0</span>]); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;queryInstalled error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 安装链码成功&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 批准链码
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 组织认可智能合约定义......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">approveCC</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeVersion</span>, <span style="color:#a6e22e">sequence</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">OrdererEndpoint</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;approveCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 查询批准
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">:=</span><span style="color:#a6e22e">queryApprovedCC</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">sequence</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>);<span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;queryApprovedCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 组织认可智能合约定义完成&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 检查智能合约是否就绪
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 检查智能合约是否就绪......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">:=</span><span style="color:#a6e22e">checkCCCommitReadiness</span>(<span style="color:#a6e22e">packageID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeVersion</span>, <span style="color:#a6e22e">sequence</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>); <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;checkCCCommitReadiness error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 智能合约已经就绪&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// Commit
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 提交智能合约定义......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">:=</span><span style="color:#a6e22e">commitCC</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeVersion</span>, <span style="color:#a6e22e">sequence</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">OrdererEndpoint</span>);<span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;commitCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 查询Commit结果
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">:=</span><span style="color:#a6e22e">queryCommittedCC</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">sequence</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>); <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;queryCommittedCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 智能合约定义提交完成&#34;</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// 初始化
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 调用智能合约初始化方法......&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span><span style="color:#f92672">:=</span><span style="color:#a6e22e">initCC</span>(<span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChaincodeID</span>, <span style="color:#a6e22e">upgrade</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">ChannelID</span>, <span style="color:#a6e22e">info</span>.<span style="color:#a6e22e">Orgs</span>[<span style="color:#ae81ff">0</span>], <span style="color:#a6e22e">sdk</span>); <span style="color:#a6e22e">err</span><span style="color:#f92672">!=</span><span style="color:#66d9ef">nil</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#66d9ef">return</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Errorf</span>(<span style="color:#e6db74">&#34;initCC error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 完成智能合约初始化&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h2 id="5启动项目">
  5、启动项目
  <a class="anchor" href="#5%e5%90%af%e5%8a%a8%e9%a1%b9%e7%9b%ae">#</a>
</h2>
<h4 id="main方法">
  main方法
  <a class="anchor" href="#main%e6%96%b9%e6%b3%95">#</a>
</h4>
<p>在项目的根目录下新建一个名为<code>main.go</code>的文件，为项目的主函数。在这里我们实现将组织通道等相关信息实例化，以及调用前面的函数实现创建通道加入通道将链码实例化。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;sdktest/sdkInit&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;os&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">const</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">cc_name</span> = <span style="color:#e6db74">&#34;simplecc&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">cc_version</span> = <span style="color:#e6db74">&#34;1.0.0&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>() {
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// init orgs information
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">orgs</span> <span style="color:#f92672">:=</span> []<span style="color:#f92672">*</span><span style="color:#a6e22e">sdkInit</span>.<span style="color:#a6e22e">OrgInfo</span>{
</span></span><span style="display:flex;"><span>		{
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">OrgAdminUser</span>:  <span style="color:#e6db74">&#34;Admin&#34;</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">OrgName</span>:       <span style="color:#e6db74">&#34;Org1&#34;</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">OrgMspId</span>:      <span style="color:#e6db74">&#34;Org1MSP&#34;</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">OrgUser</span>:       <span style="color:#e6db74">&#34;User1&#34;</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">OrgPeerNum</span>:    <span style="color:#ae81ff">1</span>,
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">OrgAnchorFile</span>: <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Getenv</span>(<span style="color:#e6db74">&#34;GOPATH&#34;</span>) <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;/src/sdktest/fixtures/channel-artifacts/Org1MSPanchors.tx&#34;</span>,
</span></span><span style="display:flex;"><span>		},
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// init sdk env info
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">info</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdkInit</span>.<span style="color:#a6e22e">SdkEnvInfo</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ChannelID</span>:        <span style="color:#e6db74">&#34;mychannel&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ChannelConfig</span>:    <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Getenv</span>(<span style="color:#e6db74">&#34;GOPATH&#34;</span>) <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;/src/sdktest/fixtures/channel-artifacts/channel.tx&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">Orgs</span>:             <span style="color:#a6e22e">orgs</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">OrdererAdminUser</span>: <span style="color:#e6db74">&#34;Admin&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">OrdererOrgName</span>:   <span style="color:#e6db74">&#34;OrdererOrg&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">OrdererEndpoint</span>:  <span style="color:#e6db74">&#34;orderer.example.com&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ChaincodeID</span>:      <span style="color:#a6e22e">cc_name</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ChaincodePath</span>:    <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Getenv</span>(<span style="color:#e6db74">&#34;GOPATH&#34;</span>) <span style="color:#f92672">+</span> <span style="color:#e6db74">&#34;/src/sdktest/chaincode/&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">ChaincodeVersion</span>: <span style="color:#a6e22e">cc_version</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// sdk setup
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">sdk</span>, <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdkInit</span>.<span style="color:#a6e22e">Setup</span>(<span style="color:#e6db74">&#34;config.yaml&#34;</span>, <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">info</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; SDK setup error:&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Exit</span>(<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// create channel and join
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdkInit</span>.<span style="color:#a6e22e">CreateAndJoinChannel</span>(<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">info</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; Create channel and join error:&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Exit</span>(<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// create chaincode lifecycle
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">sdkInit</span>.<span style="color:#a6e22e">CreateCCLifecycle</span>(<span style="color:#f92672">&amp;</span><span style="color:#a6e22e">info</span>, <span style="color:#ae81ff">1</span>, <span style="color:#66d9ef">false</span>, <span style="color:#a6e22e">sdk</span>); <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; create chaincode lifecycle error: %v&#34;</span>, <span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Exit</span>(<span style="color:#f92672">-</span><span style="color:#ae81ff">1</span>)
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>	<span style="color:#75715e">// invoke chaincode set status
</span></span></span><span style="display:flex;"><span><span style="color:#75715e"></span>	<span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Println</span>(<span style="color:#e6db74">&#34;&gt;&gt; 通过链码外部服务设置链码状态......&#34;</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><h4 id="2-添加链码文件">
  2. 添加链码文件
  <a class="anchor" href="#2-%e6%b7%bb%e5%8a%a0%e9%93%be%e7%a0%81%e6%96%87%e4%bb%b6">#</a>
</h4>
<p>在项目根目录下新建一个名为<code>chaincode</code>的文件夹&hellip;.</p>
<p><font color='red'>详情请见<a href="https://chaincode.gitee.io/docs/%e5%8c%ba%e5%9d%97%e9%93%be/fabric/2021-05-10-%e6%99%ba%e8%83%bd%e5%90%88%e7%ba%a6/">智能合约</a></font></p>
<h4 id="3-启动项目">
  3. 启动项目
  <a class="anchor" href="#3-%e5%90%af%e5%8a%a8%e9%a1%b9%e7%9b%ae">#</a>
</h4>
<p>在命令行中进入chaincode路径，并使用以下命令为链码添加依赖包。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>go mod init
</span></span><span style="display:flex;"><span>go mod vendor
</span></span></code></pre></div><p>在命令行中进入项目根目录，并使用以下命令为项目添加依赖包。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>go mod init
</span></span><span style="display:flex;"><span>go mod tidy
</span></span></code></pre></div><p>在命令行中进入fixtures路径，并使用以下命令启动网络。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>docker-compose up -d
</span></span></code></pre></div><p>在命令行中进入项目根目录，并使用以下命令build整个项目。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>go build
</span></span></code></pre></div><p>接着使用以下命令运行项目。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-shell" data-lang="shell"><span style="display:flex;"><span>./sdktest
</span></span></code></pre></div><p>运行成功后输出：</p>
<pre tabindex="0"><code>&gt;&gt; 开始创建通道......
&gt;&gt;&gt;&gt; 使用每个org的管理员身份更新锚节点配置...
&gt;&gt;&gt;&gt; 使用每个org的管理员身份更新锚节点配置完成
&gt;&gt; 创建通道成功
&gt;&gt; 加入通道......
&gt;&gt; 加入通道成功
&gt;&gt; 开始打包链码......
&gt;&gt; 打包链码成功
&gt;&gt; 开始安装链码......
&gt;&gt; 安装链码成功
&gt;&gt; 组织认可智能合约定义......
&gt;&gt;&gt; chaincode approved by Org1 peers:
        peer0.org1.example.com:7051
        peer1.org1.example.com:9051
&gt;&gt; 组织认可智能合约定义完成
&gt;&gt; 检查智能合约是否就绪......
LifecycleCheckCCCommitReadiness cc = simplecc, = {map[Org1MSP:true]}
LifecycleCheckCCCommitReadiness cc = simplecc, = {map[Org1MSP:true]}
&gt;&gt; 智能合约已经就绪
&gt;&gt; 提交智能合约定义......
&gt;&gt; 智能合约定义提交完成
&gt;&gt; 调用智能合约初始化方法......
&gt;&gt; 完成智能合约初始化
&gt;&gt; 通过链码外部服务设置链码状态......
</code></pre></article>
 
      

      <footer class="book-footer">
        
  <div class="flex flex-wrap justify-between">





</div>



  <script>(function(){function e(e){const t=window.getSelection(),n=document.createRange();n.selectNodeContents(e),t.removeAllRanges(),t.addRange(n)}document.querySelectorAll("pre code").forEach(t=>{t.addEventListener("click",function(){if(window.getSelection().toString())return;e(t.parentElement),navigator.clipboard&&navigator.clipboard.writeText(t.parentElement.textContent)})})})()</script>


 
        
      </footer>

      
  
  <div class="book-comments">

</div>
  
 

      <label for="menu-control" class="hidden book-menu-overlay"></label>
    </div>

    
    <aside class="book-toc">
      <div class="book-toc-content">
        
  
<nav id="TableOfContents">
  <ul>
    <li><a href="#fabric-go-sdk">fabric-go-sdk</a>
      <ul>
        <li><a href="#1概述">1、概述</a></li>
        <li><a href="#2准备网络环境">2、准备网络环境</a>
          <ul>
            <li><a href="#准备证书文件">准备证书文件</a></li>
          </ul>
        </li>
        <li><a href="#3配置文件configyaml">3、配置文件config.yaml</a></li>
        <li><a href="#4sdk">4、sdk</a>
          <ul>
            <li><a href="#1-定义所需结构体">1. 定义所需结构体</a></li>
            <li><a href="#2初始化">2、初始化</a></li>
            <li><a href="#3调用创建通道函数及加入通道">3、调用创建通道函数及加入通道</a></li>
            <li><a href="#4创建通道">4、创建通道</a></li>
            <li><a href="#5链码生命周期">5、链码生命周期</a></li>
          </ul>
        </li>
        <li><a href="#5启动项目">5、启动项目</a>
          <ul>
            <li></li>
          </ul>
        </li>
      </ul>
    </li>
  </ul>
</nav>


 
      </div>
    </aside>
    
  </main>

  
</body>
</html>












